package threads;

import java.util.concurrent.*;

/**
 * @author apple
 * @Classname AbortPolicyTest
 * @Description TODO
 * @Date 2020/4/19 16:46
 */
public class AbortPolicyTest {
    public static void main(String[] args) {
        AbortPolicyTest test = new AbortPolicyTest();
        /**AbortPolicy拒绝策略**/
        System.out.println("AbortPolicy");
        test.abortPolicyTest();

        System.out.println("CallerRunsPolicy");
        test.callerRunsPolicyTest();

        System.out.println("DiscardPolicy");
        test.discardPolicy();

        System.out.println("DiscardOldPolicy");
        test.discardOldPolicy();
    }

    /**
     * 线程拒绝策略 AbortPolicy,线程池的默认拒绝策略，
     * 会抛出RejectedExecutionException,必须try-catch，否则会终端当前执行流程*
     */
    public void abortPolicyTest() {
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        threadExecute(handler);
    }

    /**CallerRunsPolicy 策略
     * 当触发拒绝策略，只要线程池没有关闭的话，则使用调用线程直接运行任务。
     * 一般并发比较小，性能要求不高，不允许失败。
     * 但是，由于调用者自己运行任务，如果任务提交速度过快，可能导致程序阻塞，
     * 性能效率上必然的损失较大**/
    public void callerRunsPolicyTest(){
        RejectedExecutionHandler handler = new ThreadPoolExecutor.CallerRunsPolicy();
        threadExecute(handler);
    }

    /**DiscardPolicy 直接丢弃，其他啥都没有**/
    public void discardPolicy(){
        RejectedExecutionHandler handler=new ThreadPoolExecutor.DiscardPolicy();
        threadExecute(handler);
    }

    /**DiscardOldPolicy 只要线程池没有关闭的话，丢弃阻塞队列 workQueue 中最老的一个任务，并将新任务加入**/
    public void discardOldPolicy(){
        RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy();
        threadExecute(handler);
    }

    /**RejectExecutionHandle拒绝策略作为参数**/
    public void threadExecute(RejectedExecutionHandler handler){
        int corePoolSize = 5;
        int maximumPoolSize = 10;
        long keepAliveTime = 5;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(1);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, handler);
        for (int i = 0; i < 100; i++) {
            try {
                executor.execute(new Thread());
                System.out.println(Thread.currentThread()+ " is running");
                System.out.println("workQueue="+workQueue.remainingCapacity());
            } catch (Exception e) {
                System.out.println("something is wrong ="+ e.getMessage());
            }
        }
        executor.shutdown();
    }
}
